package com.haiqiu.security.service;


import com.haiqiu.common.result.Constants;
import com.haiqiu.common.utils.web.RedisUtil;
import com.haiqiu.security.entity.SecurityUser;
import com.haiqiu.system.entity.SysPermission;
import com.haiqiu.system.entity.SysRole;
import com.haiqiu.system.entity.SysUser;
import com.haiqiu.system.entity.vo.SysUserVo;
import com.haiqiu.system.mapper.SysRoleMapper;
import com.haiqiu.system.mapper.SysUserMapper;
import com.haiqiu.system.service.SysDeptService;
import com.haiqiu.system.service.SysPermissionService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author HaiQiu
 * @date 2021/4/4 12:12
 * @desc
 **/
@Service("UserDetailsServiceImpl")
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysPermissionService sysPermissionService;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysDeptService sysDeptService;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public UserDetails loadUserByUsername(String username) throws org.springframework.security.core.userdetails.UsernameNotFoundException {
        SysUser sysUser = sysUserMapper.selectByUsername(username);
        SecurityUser securityUser = new SecurityUser();
        BeanUtils.copyProperties(sysUser, securityUser);
        List<SysPermission> sysPermissionList = sysPermissionService.selectPermissionListByUsername(username);
        //缓存数据库查询登录的账户信息
        if (sysUser != null) {
            SysUserVo userVo = new SysUserVo();
            BeanUtils.copyProperties(sysUser, userVo);
            List<SysRole> sysRoles = sysRoleMapper.selectRoleByUserId(userVo.getId());
            List<String> rolesByName = sysRoles.stream().map(SysRole::getName).collect(Collectors.toList());
            userVo.setRoles(rolesByName);
            userVo.setDept(sysDeptService.get(userVo.getDeptId()));
            //存储到redis
            redisUtil.set(Constants.REDIS_USER_INFO + username,userVo);
        }
        //存储redis权限
        if (sysPermissionList != null && sysPermissionList.size() != 0) {
            redisUtil.set(Constants.REDIS_USER_AUTH + username, sysPermissionList);
        }
        //创建一个空的security权限集合
        Set<GrantedAuthority> authorities = new HashSet<>();
        //循环数据库查出的权限值
        for (SysPermission sysPermission : sysPermissionList) {
            //判断数据库查出的值是否存在，不存在也继续
            if (StringUtils.isEmpty(sysPermission.getValue())) {
                continue;
            }
            //将查出的值放入SimpleGrantedAuthority中
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority(sysPermission.getValue());
            //添加到空的security权限集合authorities
            authorities.add(authority);
        }
        //最后返回权限值
        securityUser.setAuthorities(authorities);
        //缓存security框架的账户信息
        redisUtil.set(Constants.REDIS_USER + securityUser.getUsername(), securityUser);
        sysUser.setLoginTime(new Date());
        sysUserMapper.updateByPrimaryKeySelective(sysUser);
        return securityUser;
    }
}
